package com.demo.proxy;

import org.apache.commons.io.FileUtils;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.Tool;
import javax.tools.ToolProvider;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Proxy {
    public static Object newProxyInstance(InvocationHandler h) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        BufferedReader br = new BufferedReader(new FileReader("src/main/java/com/demo/proxy/CarTimeProxy.java"));
        StringBuilder sb = new StringBuilder();
        String str = null;
        while ((str = br.readLine()) != null) {
            sb.append(str);
            sb.append("\r\n");
        }

        str = sb.toString();
        str = str.replace("CarTimeProxy", "$Proxy0");
        String filename = "target/classes/com/demo/proxy/$Proxy0.java";
        try {
            FileUtils.fileWrite(filename, str);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 编译
        // 拿到编译器
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        // 文件管理者
        StandardJavaFileManager fileManager =
                compiler.getStandardFileManager(null,null, null);
        // 获取文件
        Iterable units = fileManager.getJavaFileObjects(filename);
        // 编译任务
        JavaCompiler.CompilationTask t = compiler.getTask(null, fileManager, null, null, null, units);
        t.call();
        fileManager.close();

        // load到内存
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Class c = cl.loadClass("com.demo.proxy.$Proxy0");
        System.out.println(c.getName());

        Constructor ctr = c.getConstructor(Moveable.class);
        return ctr.newInstance(new Car());
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        Moveable moveable = (Moveable) newProxyInstance(new TimeHandler(new Car()));
        moveable.move();
    }
}
